/*
 * Copyright (c) 2008, Hugh Sanderson, http://gamehaxe.com/
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 *
 */
 
import flash.display.Graphics;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;

import flash.display.CapsStyle;
import flash.display.GradientType;
import flash.display.JointStyle;
import flash.display.SpreadMethod;
import flash.display.LineScaleMode;
import flash.geom.Matrix;
import flash.events.Event;


class GraphicsTest extends Sprite
{
   static function main()
   {
      neash.Lib.Init("GraphicsTest",640,480,false,true); 
      neash.Lib.SetBackgroundColour(0xffffff); 

      new GraphicsTest();

      neash.Lib.SetFrameRate(1000);
      neash.Lib.ShowFPS();
      neash.Lib.Run(); 
   }


   static var mx = -40;
   static var rot = 0.0;
   static var phase = 0.0;

   var square : Shape;
   var grad_circle : Shape;
   var lines : Shape;
   var rad_grad : Shape;
   var bitmap_obj : Shape;

   public function new()
   {
      super();
      flash.Lib.current.addChild(this);

      // nme.display.Graphics.defaultFontName = "../common/ARIAL.TTF";

      square = new Shape();
      var gfx = square.graphics;
      gfx.beginFill(0x0000ff);
      gfx.drawRect(-10,-10,20,20);
      gfx.moveTo(0,0);
      //gfx.text("Square",12,null,null,Graphics.CENTER,Graphics.CENTER);

      square.x = 400;
      square.y = 300;


      grad_circle = new Shape();

      var colours = [ 0xff0000, 0x000000 ];
      var alphas = [ 1.0, 1.0 ];
      var ratios = [ 0, 255 ];
      var mtx = new Matrix();
      mtx.createGradientBox(100,100,Math.PI/6,150,100);

      gfx = grad_circle.graphics;
      gfx.beginGradientFill(GradientType.LINEAR,
                       colours, alphas, ratios, mtx, SpreadMethod.PAD);
      gfx.drawCircle(200,150,75);

      addChild(grad_circle);
      grad_circle.cacheAsBitmap;

      lines = new Shape();
      gfx = lines.graphics;
      gfx.lineStyle(1,0x0000ff);
      gfx.moveTo(50,100);
      gfx.lineTo(50,400);

      gfx.lineStyle(20,0x000000,0.5,false,LineScaleMode.NORMAL,
               CapsStyle.ROUND, JointStyle.ROUND );

      gfx.moveTo(50,300);
      gfx.lineTo(200,300);
      gfx.lineTo(250,200);

      gfx.lineStyle(20,0x000000,0.5,false,LineScaleMode.NORMAL,
               CapsStyle.SQUARE, JointStyle.BEVEL );

      gfx.moveTo(50,330);
      gfx.lineTo(220,330);
      gfx.lineTo(270,230);

      gfx.lineStyle(20,0x000000,0.5,false,LineScaleMode.NORMAL,
               CapsStyle.NONE, JointStyle.MITER );

      gfx.moveTo(50,360);
      gfx.lineTo(240,360);
      gfx.lineTo(290,260);

      addChild(lines);
      lines.cacheAsBitmap = true;

      rad_grad = new Shape();
      var gfx = rad_grad.graphics;
      var mtx = new Matrix();
      // Define positive quadrant ...
      mtx.createGradientBox(100,100, 0, 0,0);
      gfx.beginGradientFill(GradientType.RADIAL,
                       colours, alphas, ratios, mtx, SpreadMethod.REPEAT,
                       -0.9 );
      gfx.drawRect(0,0,100,100);

      addChild(rad_grad);
      rad_grad.cacheAsBitmap = true;



      bitmap_obj = new Shape();
      var gfx = bitmap_obj.graphics;

#if !flash
      var bmp = new BitmapData(32,32,false,neash.RGB.WHITE);
      bmp.graphics.beginFill(0xff5050);
      bmp.graphics.drawCircle(6,6,5);
      bmp.graphics.drawCircle(22,22,5);
      bmp.graphics.flush();
#else
      var bmp = new BitmapData(32,32);
      var drawing = new Shape();
      drawing.graphics.beginFill(0xff5050);
      drawing.graphics.drawCircle(6,6,5);
      drawing.graphics.drawCircle(22,22,5);
      bmp.draw(drawing);
#end
      gfx.lineStyle(1,0x000000);
      var matrix = new Matrix();
      matrix.a = 2;
      matrix.tx = 20;
      matrix.ty = 20;
      gfx.beginBitmapFill(bmp,matrix,false,true);
      gfx.drawRoundRect(0,0,100,80,10,10);
      bitmap_obj.x = 400;
      bitmap_obj.y = 300;
      addChild(bitmap_obj);

      var tri = new Shape();
      var gfx = tri.graphics;
      var vertices = new flash.Vector<Float>();
      vertices.push(300); vertices.push(30);
      vertices.push(400); vertices.push(130);
      vertices.push(250); vertices.push(130);
      gfx.beginFill(0x0000ff);
      gfx.drawTriangles(vertices);


      addChild(tri);

      addEventListener(Event.ENTER_FRAME, OnEnterFrame);
   }

/*
   public function onRender()
   {
      manager.clear( 0x606060 );

      var gfx = Manager.graphics;

      gfx.clear();

      gfx.moveTo(10,10);
      gfx.lineStyle(1,0xff0000);
      gfx.lineTo(100,100);
      gfx.lineStyle(3,0x00ff00);
      gfx.lineTo(200,200);
      gfx.lineStyle(5,0x0000ff);
      gfx.lineTo(300,300);
      // Call flush now to ensure lines drawn before circle etc...
      gfx.flush();

      // This has already been setup.
      grad_circle.draw();
      square.draw();
      lines.draw();
      rad_grad.draw();

      var rect = square.extent;

      gfx.lineStyle(1,0x00ff00);
      gfx.drawRect(rect.x,rect.y,rect.width,rect.height);

      // Drawing to the managers graphics draws immediately.
      // This is not as efficient as building a display object.
      gfx.lineStyle(20,0x007733,1,false, LineScaleMode.NORMAL,
               CapsStyle.ROUND, JointStyle.ROUND, 5.0 );
      gfx.moveTo(0,0);
      gfx.curveTo(wndWidth/2,wndHeight,wndWidth,0);
      gfx.flush();

      gfx.clipRect = new nme.geom.Rectangle(60,0,wndWidth-120,wndHeight);
      gfx.lineStyle(3,0x0000ff);
      gfx.beginFill(0xff3030);
      gfx.drawEllipse(x,100,80,60);

      gfx.moveTo(x,100);

      gfx.lineStyle(1,0x00ff80);
      gfx.text("Hello!",24,null,0xffffff,Graphics.CENTER,Graphics.CENTER);

      gfx.endFill();
      gfx.clipRect = null;

      gfx.moveTo(wndWidth*0.5,wndHeight*0.5);
      gfx.lineTo(x,100);

      gfx.lineStyle(20,0x000000,1,false,LineScaleMode.NORMAL,
               CapsStyle.ROUND, JointStyle.MITER, 5.0 );
      gfx.moveTo(wndWidth*0.6,95);
      gfx.lineTo(wndWidth*0.6,100);
      gfx.lineTo(wndWidth*0.6 + 50*Math.cos(phase),
                 100 + 50*Math.sin(phase));


      gfx.lineStyle(2);
      var lcolours = [ 0x303030, 0xd0d0d0 ];
      var lalphas = [ 1.0, 1.0 ];
      var lratios = [ 0, 255 ];
      var lmtx = new Matrix();
      lmtx.createGradientBox(64,64,Math.PI*0.5,0,398);
      gfx.lineGradientStyle(GradientType.LINEAR,
                       lcolours, lalphas, lratios, lmtx, SpreadMethod.PAD);



      var colours = [ 0xd0d0d0, 0x606060, 0x000000, 0x505000 ];
      var alphas = [ 1.0, 1.0 , 1.0, 1.0];
      var ratios = [ 0, 128, 150, 255 ];
      var mtx = new Matrix();
      mtx.createGradientBox(60,60,Math.PI*0.5,0,400);
      gfx.beginGradientFill(GradientType.LINEAR,
                       colours, alphas, ratios, mtx, SpreadMethod.PAD);

      gfx.drawRoundRect(100,400,200,60, 10, 10 );

      bitmap_obj.draw();

      gfx.flush();

   }
*/

   public function onUpdate(inDT:Float)
   {
      // You can set the matrix to move the display object around.
      var matrix = new Matrix();
      //matrix.setRotation(rot, Math.abs(Math.sin(phase)*10.0));
      matrix.tx = 300;
      matrix.ty = 200;
      square.transform.matrix = matrix;

      //bitmap_obj.matrix.setRotation(rot, (2+Math.sin(phase*-4.0))*0.25);
      //bitmap_obj.matrix.tx = (0.5-0.4*Math.sin(phase*1.0))*wndWidth;

  
      mx = mx+1;
      if (mx>600) mx = -10;

      rot += 0.01;
      phase += 0.01;

      var scale = new Matrix();
      scale.scale(2.0,3.0);

      matrix = new Matrix();
      matrix.rotate(1);

      var translate = new Matrix();
      translate.translate(mx,0);
      matrix.scale(3,1);
      translate.concat(matrix);

      bitmap_obj.transform.matrix = translate;
   }

   function OnEnterFrame(inEvent:Event)
   {
     onUpdate(0.03);
   }
}
